package com.pantuo.sys.service.impl;

import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.conditions.update.UpdateWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.pantuo.common.exception.ServiceException;
import com.pantuo.common.utils.DataTablePage;
import com.pantuo.common.utils.MD5Util;
import com.pantuo.common.utils.TableRequest;
import com.pantuo.sys.dao.CommonDao;
import com.pantuo.sys.dao.UserDao;
import com.pantuo.sys.dao.UserPermissionDao;
import com.pantuo.sys.pojo.User;
import com.pantuo.sys.service.UserService;
import com.pantuo.sys.vo.UserPermissionVo;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.domain.PageImpl;
import org.springframework.data.domain.PageRequest;
import org.springframework.stereotype.Service;
import org.springframework.util.DigestUtils;

import java.math.BigInteger;
import java.util.*;

@Service
public class UserServiceImpl implements UserService {

    @Autowired
    private UserDao userDao;
    @Autowired
    private UserPermissionDao userPermissionDao;
    @Autowired
    private CommonDao commonDao;


    /**
     * 用户登入
     *
     * @param map
     * @return
     */
    @Override
    public Map<String, Object> login(Map<String, String> map) {
        String username_s = map.get("username_s");
        String password_s = map.get("password_s");
        Map<String, Object> loginMap = new HashMap<>();
        QueryWrapper<User> queryWrapper1 = new QueryWrapper<>();
        queryWrapper1.eq("username_s", username_s);
        User user1 = userDao.selectOne(queryWrapper1);
        //用户名不存在
        if (user1 == null) {
            throw new ServiceException("用户不存在");
        }
        //用户名存在后再比对密码
        QueryWrapper<User> queryWrapper2 = new QueryWrapper<>();
        //MD5加密后再比对
        String newPassword = MD5Util.encode(password_s);
        System.out.println(newPassword);
        queryWrapper2
                .eq("username_s", username_s)
                .eq("password_s", newPassword);
        User user = userDao.selectOne(queryWrapper2);
        //用户为空：密码错误
        if (user == null) {
            throw new ServiceException("密码错误");
        } else {
            //UserPermissionVo userAndPer = userDao.findUserAndPer(user.getId());
            return findUserAndPer(user.getId());
        }
    }

    /**
     * 添加用户
     *
     * @param map
     */
    @Override
    public void insertObject(Map<String, String> map, Integer[] permissionId_i) {
        if (StringUtils.isEmpty(map.get("username_s"))) {
            throw new ServiceException("用户名不能为空");
        }
        if (StringUtils.isEmpty(map.get("password1_s"))) {
            throw new ServiceException("密码不能为空");
        }
        if (StringUtils.isEmpty(map.get("password2_s"))) {
            throw new ServiceException("确认密码时不能为空");
        }
        if (!map.get("password1_s").equals(map.get("password2_s"))) {
            throw new ServiceException("前后密码不一致");
        }
        User user = new User();
        user.setUsername_s((String) map.get("username_s"));
        //MD5加密后再设置进去
        user.setPassword_s(MD5Util.encode(map.get("password2_s")));
        user.setEmail_s((String) map.get("email_s"));
        user.setPhone_s((String) map.get("phone_s"));
        //保存用户
        userDao.insert(user);
        //保存用户与权限关系(中间表)
        //userPermissionDao.insertObjects(user.getId(), permissionId_i);
    }

    /**
     * 修改密码
     *
     * @param username
     * @param usedPassword
     * @param newPassword1
     * @param newPassword2
     * @return
     */
    @Override
    public void updatePwd(String username,
                          String usedPassword,
                          String newPassword1,
                          String newPassword2) {

        if (StringUtils.isEmpty(username)) {
            throw new ServiceException("请输入用户名");
        }
        if (StringUtils.isEmpty(usedPassword)) {
            throw new ServiceException("原密码不能为空");
        }
        if (StringUtils.isEmpty(newPassword1)) {
            throw new ServiceException("新密码不能为空");
        }
        if (StringUtils.isEmpty(newPassword2)) {
            throw new ServiceException("确认新密码不能为空");
        }
        QueryWrapper<User> queryWrapper = new QueryWrapper<>();
        queryWrapper.eq("username_s", username);
        User user = userDao.selectOne(queryWrapper);
        String password_s = user.getPassword_s();
        String md5UsedPassword = MD5Util.encode(usedPassword);
        //如果输入的原密码与原密码不匹配
        if (!password_s.equals(md5UsedPassword)) {
            System.out.println(usedPassword);
            System.out.println(password_s);
            throw new ServiceException("原密码输入有误");
        }
        //如果输入的新密码前后不一致
        if (!newPassword1.equals(newPassword2)) {
            throw new ServiceException("新密码前后不一致");
        }
        //如果都匹配则修改密码
        UpdateWrapper<User> updateWrapper = new UpdateWrapper<>();
        updateWrapper
                .set("password_s", MD5Util.encode(newPassword2))
                .eq("username_s", username);
        userDao.update(user, updateWrapper);
    }


    /**
     * 查询用户列表并分页，因为用户信息中包含用户密码
     * 只能查询用户的指定字段，所以不能走通用接口实现
     *
     * @param request
     * @return
     */
    @Override
    public PageImpl<UserPermissionVo> findPageObjects(TableRequest request) {
        //获取起始索引
        int start = request.getStart();
        //获取页面大小
        int length = request.getLength();
        //当前页
        int current = start / length + 1;
        Page<User> userPage = new Page<>(current, length);
        //获取查询条件，用map封装
        Map<String, String> filter = request.getFilter();
        //获取排序字段和排序规则 asc or desc
        List<Map<String, String>> orderList = request.getOrder();
        Map<String, String> orderMap = null;
        //创建查询构造器
        QueryWrapper<User> queryWrapper = new QueryWrapper<>();
        //所要查询的用户字段
        queryWrapper.select("id", "username_s", "email_s", "phone_s", "remarks_s", "created_dt", "updated_dt");
        IPage<User> userIPage = null;
        //一页数据的集合
        List<User> userRecords = null;
        //总记录数
        long total = 0;
        //如果排序条件为空则默认按照创建时间排序(最后创建的用户排在最前面)
        if (orderList == null) {
            queryWrapper.orderByDesc("created_dt");
            //查询为空
            if (filter == null) {
                userIPage = userDao.selectPage(userPage, queryWrapper);
                userRecords = userIPage.getRecords();
                total = userIPage.getTotal();
                return new DataTablePage(new PageImpl<User>(userRecords, PageRequest.of(start, length), total));
            }
            //查询不为空
            if (filter != null) {
                Set<String> keySet = filter.keySet();
                for (String key : keySet) {
                    queryWrapper.like(key, filter.get(key));
                }
                userIPage = userDao.selectPage(userPage, queryWrapper);
                userRecords = userIPage.getRecords();
                total = userIPage.getTotal();
                return new DataTablePage(new PageImpl<User>(userRecords, PageRequest.of(start, length), total));
            }
        }
        //排序条件不为空则按照指定的规则进行排序
        if (orderList != null) {
            //查询条件为空
            if (filter == null) {
                orderMap = orderList.get(0);
                Set<String> keySet = orderMap.keySet();
                for (String key : keySet) {
                    String order = orderMap.get(key);
                    //判断是升序还是降序
                    boolean flag = order.equals("asc") ? true : false;
                    queryWrapper.orderBy(true, flag, key);
                }
                userIPage = userDao.selectPage(userPage, queryWrapper);
                userRecords = userIPage.getRecords();
                total = userIPage.getTotal();
                return new DataTablePage(new PageImpl<User>(userRecords, PageRequest.of(start, length), total));
            }
            //查询条件不为空
            if (filter != null) {
                Set<String> filterColumns = filter.keySet();
                for (String filterColumn : filterColumns) {
                    queryWrapper.like(filterColumn, filter.get(filterColumn));
                }
                orderMap = orderList.get(0);
                Set<String> orderColumns = orderMap.keySet();
                for (String orderColumn : orderColumns) {
                    String order = orderMap.get(orderColumn);
                    //判断是升序还是降序
                    boolean flag = order.equals("asc") ? true : false;
                    queryWrapper.orderBy(true, flag, orderColumn);
                }
                userIPage = userDao.selectPage(userPage, queryWrapper);
                userRecords = userIPage.getRecords();
                total = userIPage.getTotal();
                return new DataTablePage(new PageImpl<User>(userRecords, PageRequest.of(start, length), total));
            }
        }
        return null;
    }

    @Override
    public void deleteObject(Integer id) {
        //删除关系数据
        userPermissionDao.deleteUserAndPer(id);
        //删除用户自身数据
        int row = userDao.deleteById(id);
        if (row == 0) {
            throw new ServiceException("用户可能不存在");
        }
    }

    @Override
    public void updateUser(Map<String, Object> userMap) {
        //先更新用户信息
        userMap.put("className", "tn_user");

        //先判断userMap中是否包含id，包含id则更新，不包含则保存
        if (userMap.containsKey("id")) {
            commonDao.updateObject(userMap);
        } else {
            userMap.put("password_s", MD5Util.encode((String) userMap.get("password_s")));
            commonDao.insertObject(userMap);
        }
        System.out.println(userMap);

        //其次更新用户权限
        String json = (String) userMap.get("json");
        Map<String, Boolean> jsonMap = (Map) JSON.parse(json);
        System.out.println(jsonMap);
        Set<String> permissions = jsonMap.keySet();
        List<Integer> permissionIds = new ArrayList<>();
        int userId = Integer.parseInt(userMap.get("id").toString());
        for (String permission : permissions) {
            if (jsonMap.get(permission)) {
                //保存用户权限中间表信息之前先将用户对应的中间表信息删除
                userPermissionDao.deleteUserAndPer(userId);
                Integer permissionId = userPermissionDao.findIdByField(permission);
                permissionIds.add(permissionId);
            }
        }
        //中间表信息删除完后保存中间表信息
        userPermissionDao.insertObjects(userId, permissionIds);
    }

    /**
     * 根据用户id查询用户信息及其权限信息
     *
     * @param id
     * @return
     */
    @Override
    public Map<String, Object> findUserAndPer(Integer id) {
        UserPermissionVo userAndPer = userDao.findUserAndPer(id);
        List<String> codeList = userAndPer.getCode_s();
        Map<String, Object> userAndPerMap = new HashMap<>();
        Map<String, Object> jsonMap = new HashMap<>();
        for (String code : codeList) {
            jsonMap.put(code, true);
        }
        userAndPerMap.put("username_s", userAndPer.getUsername_s());
        userAndPerMap.put("email_s", userAndPer.getEmail_s());
        userAndPerMap.put("phone_s", userAndPer.getPhone_s());
        //将jsonMap转为json串
        JSONObject json = new JSONObject(jsonMap);
        userAndPerMap.put("code_s", json);
        //或者不用转直接将jsonMap放入到userAndPerMap，@ResponseBody注解会自动将map转为json串
        //userAndPerMap.put("code_s", jsonMap);
        return userAndPerMap;
    }

    /**
     * 重置密码
     *
     * @param id
     */
    @Override
    public void resetPwd(Integer id) {
        if (id == null) {
            throw new ServiceException("请传入id");
        }
        String newPwd = "123456";
        String encode = MD5Util.encode(newPwd);
        userDao.resetPwd(id, encode);
    }


}
